package blogcatback.service.serviceImp;

import blogcatback.constants.CommonConst;
import blogcatback.entity.Result;
import blogcatback.entity.User;
import blogcatback.enums.BlogCatEnum;
import blogcatback.mapper.UserMapper;
import blogcatback.service.UserService;
import blogcatback.utils.cache.BlogCatCache;
import blogcatback.vo.UserVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.UUID;

/**
 * @author Lijingjing
 * @date 2024/8/29 15:49
 * @description UserServiceImpl
 */
@Primary
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService {


    //多种登录（用户名/邮箱/手机号）方式,且需要区分角色【管理员和一般用户】
    @Override
    public Result<UserVO> login(String account, String password,boolean isAdmin) {

        //1.前端传来的数据是否经过了加密处理？如果是，那么需要使用对应的解密技术进行解密

        // DigestUtils.md5DigestAsHex(password.getBytes()))这就是将密码转成哈希值而已，也是一种什么加密方式？
        User one = lambdaQuery().and(wrapper->wrapper.eq(User::getUsername, account)
                .or()
                .eq(User::getEmail,account)
                .or()
                .eq(User::getPhoneNumber,account))
                .eq(User::getPassword, DigestUtils.md5DigestAsHex(password.getBytes()))
                .one();

        if (one == null) {
            return Result.error("用户名/密码错误，请重新输入！");
        }

        if(!one.getUserStatus()){
            return Result.error("账号被冻结");
        }

        String adminToken = "";
        String userToken = "";
        //验证是否为管理员
        if(isAdmin){
            if(one.getUserType() != BlogCatEnum.USER_TYPE_ADMIN.getCode() && one.getUserType() != BlogCatEnum.USER_TYPE_USER.getCode()){
                return Result.error("您输入的不是管理员账号，请输入管理员账号！");
            }
            //如果缓存中已有admin的token，则从缓存中获取admin的token
            if(BlogCatCache.get(CommonConst.ADMIN_TOKEN+one.getId())!=null){
                adminToken = (String)BlogCatCache.get(CommonConst.ADMIN_TOKEN+one.getId());
            }
        }else{
            //普通用户情况
            if(BlogCatCache.get(CommonConst.USER_TOKEN+one.getId())!=null){
                userToken = (String)BlogCatCache.get(CommonConst.USER_TOKEN+one.getId());
            }
        }

        //处理token
        if(isAdmin && !StringUtils.hasText(adminToken)){
            //是管理员，但是没有token
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            adminToken = CommonConst.ADMIN_ACCESS_TOKEN+uuid;
            //将token与用户绑定
            BlogCatCache.put(adminToken,one,CommonConst.TOKEN_EXPIRE);
            BlogCatCache.put(CommonConst.ADMIN_TOKEN+one.getId(),adminToken,CommonConst.TOKEN_EXPIRE);
        }else if(!isAdmin &&!StringUtils.hasText(userToken)){
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            userToken = CommonConst.USER_ACCESS_TOKEN+uuid;
            BlogCatCache.put(userToken,one,CommonConst.TOKEN_EXPIRE);
            BlogCatCache.put(CommonConst.USER_TOKEN+one.getId(),userToken,CommonConst.TOKEN_EXPIRE);
        }

        //将User转成UserVO，让密码不传到view
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(one,userVO);
        userVO.setPassword(null);
        //处理前端显示
        //user_type = 0，isBoss要=true
        if(isAdmin &&one.getUserType() ==BlogCatEnum.USER_TYPE_ADMIN.getCode()){
            userVO.setIsBoss(true);
        }
        if(isAdmin){
            userVO.setAccessToken(adminToken);
        }else{
            userVO.setAccessToken(userToken);
        }

        return Result.success(userVO);
    }

    //注册，可通过邮箱或者手机号注册
    @Override
    public Result<UserVO> regist(UserVO userVO) {
        //1.限制用户名不能是11位数字？为什莫，就算跟手机号一样会怎么？？
        String regex = "\\d{11}";
        if(userVO.getUsername().matches(regex)){
            return Result.error("用户名不能是11位数字");
        }
        if(userVO.getUsername().contains("@")){
            return Result.error("用户名不能含有@");
        }
        //Q:此处如果可以多种方式注册,那么需要在前端设计一个切换
        if(StringUtils.hasText(userVO.getPhoneNumber())&&StringUtils.hasText(userVO.getEmail())){
            return Result.error("手机号和邮箱只能选择一个");
        }

        //验证手机号登录【在点击注册按钮之前，验证码就已经发放了，所以此处是一个验证验证码是否匹配的操作
        if(StringUtils.hasText(userVO.getPhoneNumber())){
           Integer codeCache = (Integer) BlogCatCache.get(CommonConst.FORGET_PASSWORD+userVO.getPhoneNumber()+"_1");
           if(codeCache==null||codeCache!=Integer.parseInt(userVO.getCode())){
               return Result.error("验证码错误！");
           }
        }else if(StringUtils.hasText(userVO.getEmail())){
            Integer codeCache = (Integer)BlogCatCache.get(CommonConst.FORGET_PASSWORD+userVO.getEmail()+"_2");
            if(codeCache==null||codeCache!=Integer.parseInt(userVO.getCode())){
                return Result.error("验证码错误！");
            }
        }else{
            return Result.error("请输入手机号或邮箱");
        }
        //前端传来的密码是加密之后的吗？如果是的话那需要先解密
        //userVO.setPassword(new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(user.getPassword())));

        //来处理重复问题[用户名重复，手机号重复，邮箱重复]
        if(StringUtils.hasText(userVO.getUsername())){
            Long count = lambdaQuery().eq(User::getUsername, userVO.getUsername()).count();
            if(count>0){
                return Result.error("用户名重复！");
            }
        }

        if(StringUtils.hasText(userVO.getPhoneNumber())){
            Long count = lambdaQuery().eq(User::getPhoneNumber, userVO.getPhoneNumber()).count();
            if(count>0){
                return Result.error("手机号重复！");
            }
        }else if(StringUtils.hasText(userVO.getEmail())){
            Long count = lambdaQuery().eq(User::getEmail, userVO.getEmail()).count();
            if(count>0){
                return Result.error("邮箱重复！");
            }
        }

        //处理存入数据库中的值
        User user = new User();
        user.setUsername(userVO.getUsername());
        user.setPhoneNumber(userVO.getPhoneNumber());
        user.setEmail(userVO.getEmail());
        //后端使用加密技术，将密码存入
        user.setPassword(DigestUtils.md5DigestAsHex(userVO.getPassword().getBytes()));
        //user.setAvatar();为什莫要传入头像，注册的时候又没有头像
        save(user);

        //找到数据库中对应的信息
        User one = lambdaQuery().eq(User::getId, user.getId()).one();

        //将用户的token保存下，方便下次快速登录
        String userToken = CommonConst.USER_ACCESS_TOKEN+ UUID.randomUUID().toString().replaceAll("-","");
        BlogCatCache.put(userToken,user,CommonConst.TOKEN_EXPIRE);
        BlogCatCache.put(CommonConst.USER_TOKEN+one.getId(),userToken,CommonConst.TOKEN_EXPIRE);

        //更新UserVO中token的信息
        UserVO userVO1 = new UserVO();
        BeanUtil.copyProperties(one,userVO1);
        userVO1.setPassword(null);
        userVO1.setAccessToken(userToken);
        return null;
    }


}
